package org.dxy.trigger.http.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dxy.api.dto.request.materialGroup.CreateMaterialGroupRequest;
import org.dxy.api.dto.request.materialGroup.UpdateMaterialGroupRequest;
import org.dxy.api.response.R;
import org.dxy.infrastructure.entity.query.MaterialGroupViewEntity;
import org.dxy.infrastructure.persistent.service.MaterialGroupViewService;
import org.dxy.trigger.http.service.MaterialGroupApplicationService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 物料群组应用服务实现类
 * @author dxy
 * @createTime 2025/9/5
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class MaterialGroupApplicationServiceImpl implements MaterialGroupApplicationService {
    
    private final MaterialGroupViewService materialGroupViewService;

    @Transactional
    @Override
    public R<Long> create(CreateMaterialGroupRequest request) {
        try {
            log.info("开始创建物料群组: groupCode={}, groupName={}, groupType={}", 
                    request.getGroupCode(), request.getGroupName(), request.getGroupType());
            
            // 检查群组编码是否已存在
            if (materialGroupViewService.existsByGroupCode(request.getGroupCode())) {
                return R.fail("群组编码已存在");
            }
            
            // 如果指定了父群组，检查父群组是否存在
            if (request.getParentGroupId() != null) {
                MaterialGroupViewEntity parentGroup = materialGroupViewService.getById(request.getParentGroupId());
                if (parentGroup == null) {
                    return R.fail("父群组不存在");
                }
            }
            
            // 创建物料群组实体
            MaterialGroupViewEntity entity = MaterialGroupViewEntity.builder()
                    .groupCode(request.getGroupCode())
                    .groupName(request.getGroupName())
                    .description(request.getDescription())
                    .status(StringUtils.hasText(request.getStatus()) ? request.getStatus() : "ACTIVE")
                    .groupType(request.getGroupType())
                    .parentGroupId(request.getParentGroupId())
                    .sortOrder(request.getSortOrder())
                    .build();
            
            // 保存到数据库
            materialGroupViewService.save(entity);
            
            log.info("物料群组创建成功: id={}, groupCode={}", entity.getId(), entity.getGroupCode());
            return R.ok(entity.getId());
            
        } catch (Exception e) {
            log.error("创建物料群组失败: {}", e.getMessage(), e);
            return R.fail("创建物料群组失败: " + e.getMessage());
        }
    }

    @Transactional
    @Override
    public R<Void> update(Long groupId, UpdateMaterialGroupRequest request) {
        try {
            log.info("开始更新物料群组: groupId={}, groupName={}", groupId, request.getGroupName());
            
            // 检查群组是否存在
            MaterialGroupViewEntity existingEntity = materialGroupViewService.getById(groupId);
            if (existingEntity == null) {
                return R.fail("物料群组不存在");
            }
            
            // 如果指定了父群组，检查父群组是否存在且不是自己
            if (request.getParentGroupId() != null) {
                if (request.getParentGroupId().equals(groupId)) {
                    return R.fail("不能将自己设置为父群组");
                }
                MaterialGroupViewEntity parentGroup = materialGroupViewService.getById(request.getParentGroupId());
                if (parentGroup == null) {
                    return R.fail("父群组不存在");
                }
            }
            
            // 更新实体属性
            existingEntity.setGroupName(request.getGroupName());
            existingEntity.setDescription(request.getDescription());
            if (StringUtils.hasText(request.getStatus())) {
                existingEntity.setStatus(request.getStatus());
            }
            if (StringUtils.hasText(request.getGroupType())) {
                existingEntity.setGroupType(request.getGroupType());
            }
            existingEntity.setParentGroupId(request.getParentGroupId());
            existingEntity.setSortOrder(request.getSortOrder());
            
            // 保存更新
            materialGroupViewService.updateById(existingEntity);
            
            log.info("物料群组更新成功: groupId={}", groupId);
            return R.ok();
            
        } catch (Exception e) {
            log.error("更新物料群组失败: groupId={}, error={}", groupId, e.getMessage(), e);
            return R.fail("更新物料群组失败: " + e.getMessage());
        }
    }

    @Transactional
    @Override
    public R<Void> enable(Long groupId) {
        try {
            log.info("开始启用物料群组: groupId={}", groupId);
            
            MaterialGroupViewEntity entity = materialGroupViewService.getById(groupId);
            if (entity == null) {
                return R.fail("物料群组不存在");
            }
            
            entity.setStatus("ACTIVE");
            materialGroupViewService.updateById(entity);
            
            log.info("物料群组启用成功: groupId={}", groupId);
            return R.ok();
            
        } catch (Exception e) {
            log.error("启用物料群组失败: groupId={}, error={}", groupId, e.getMessage(), e);
            return R.fail("启用物料群组失败: " + e.getMessage());
        }
    }

    @Transactional
    @Override
    public R<Void> disable(Long groupId) {
        try {
            log.info("开始禁用物料群组: groupId={}", groupId);
            
            MaterialGroupViewEntity entity = materialGroupViewService.getById(groupId);
            if (entity == null) {
                return R.fail("物料群组不存在");
            }
            
            entity.setStatus("INACTIVE");
            materialGroupViewService.updateById(entity);
            
            log.info("物料群组禁用成功: groupId={}", groupId);
            return R.ok();
            
        } catch (Exception e) {
            log.error("禁用物料群组失败: groupId={}, error={}", groupId, e.getMessage(), e);
            return R.fail("禁用物料群组失败: " + e.getMessage());
        }
    }

    @Transactional
    @Override
    public R<Void> delete(Long groupId) {
        try {
            log.info("开始删除物料群组: groupId={}", groupId);
            
            // 检查是否存在子群组
            long childCount = materialGroupViewService.countByParentGroupId(groupId);
            if (childCount > 0) {
                return R.fail("存在子群组，无法删除");
            }
            
            // TODO: 检查是否有关联的物料
            // 这里可以添加检查物料关联的逻辑
            
            // 逻辑删除
            materialGroupViewService.removeById(groupId);
            
            log.info("物料群组删除成功: groupId={}", groupId);
            return R.ok();
            
        } catch (Exception e) {
            log.error("删除物料群组失败: groupId={}, error={}", groupId, e.getMessage(), e);
            return R.fail("删除物料群组失败: " + e.getMessage());
        }
    }

    @Transactional
    @Override
    public R<Void> batchDelete(List<Long> groupIds) {
        try {
            log.info("开始批量删除物料群组: groupIds={}", groupIds);
            
            if (groupIds == null || groupIds.isEmpty()) {
                return R.fail("请选择要删除的群组");
            }
            
            // 检查每个群组是否可以删除
            for (Long groupId : groupIds) {
                long childCount = materialGroupViewService.countByParentGroupId(groupId);
                if (childCount > 0) {
                    MaterialGroupViewEntity group = materialGroupViewService.getById(groupId);
                    String groupName = group != null ? group.getGroupName() : "ID:" + groupId;
                    return R.fail("群组【" + groupName + "】存在子群组，无法删除");
                }
            }
            
            // 批量删除
            materialGroupViewService.removeByIds(groupIds);
            
            log.info("批量删除物料群组成功: count={}", groupIds.size());
            return R.ok();
            
        } catch (Exception e) {
            log.error("批量删除物料群组失败: error={}", e.getMessage(), e);
            return R.fail("批量删除物料群组失败: " + e.getMessage());
        }
    }

    @Override
    public R<Page<MaterialGroupViewEntity>> list(Page<MaterialGroupViewEntity> page, MaterialGroupViewEntity query) {
        try {
            log.debug("查询物料群组列表: page={}, query={}", page.getCurrent(), query);
            
            LambdaQueryWrapper<MaterialGroupViewEntity> wrapper = new LambdaQueryWrapper<>();
            
            // 构建查询条件
            if (StringUtils.hasText(query.getGroupCode())) {
                wrapper.like(MaterialGroupViewEntity::getGroupCode, query.getGroupCode());
            }
            if (StringUtils.hasText(query.getGroupName())) {
                wrapper.like(MaterialGroupViewEntity::getGroupName, query.getGroupName());
            }
            if (StringUtils.hasText(query.getStatus())) {
                wrapper.eq(MaterialGroupViewEntity::getStatus, query.getStatus());
            }
            if (StringUtils.hasText(query.getGroupType())) {
                wrapper.eq(MaterialGroupViewEntity::getGroupType, query.getGroupType());
            }
            if (query.getParentGroupId() != null) {
                wrapper.eq(MaterialGroupViewEntity::getParentGroupId, query.getParentGroupId());
            }
            
            // 排序
            wrapper.orderByAsc(MaterialGroupViewEntity::getId);

            Page<MaterialGroupViewEntity> result = materialGroupViewService.page(page, wrapper);
            
            return R.ok(result);
            
        } catch (Exception e) {
            log.error("查询物料群组列表失败: error={}", e.getMessage(), e);
            return R.fail("查询物料群组列表失败: " + e.getMessage());
        }
    }

    @Override
    public R<MaterialGroupViewEntity> getById(Long groupId) {
        try {
            log.debug("查询物料群组详情: groupId={}", groupId);
            
            MaterialGroupViewEntity entity = materialGroupViewService.getById(groupId);
            if (entity == null) {
                return R.fail("物料群组不存在");
            }
            
            return R.ok(entity);
            
        } catch (Exception e) {
            log.error("查询物料群组详情失败: groupId={}, error={}", groupId, e.getMessage(), e);
            return R.fail("查询物料群组详情失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<MaterialGroupViewEntity>> getByParentGroupId(Long parentGroupId) {
        try {
            log.debug("查询子群组列表: parentGroupId={}", parentGroupId);
            
            List<MaterialGroupViewEntity> list = materialGroupViewService.getByParentGroupId(parentGroupId);
            return R.ok(list);
            
        } catch (Exception e) {
            log.error("查询子群组列表失败: parentGroupId={}, error={}", parentGroupId, e.getMessage(), e);
            return R.fail("查询子群组列表失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<MaterialGroupViewEntity>> getRootGroups() {
        try {
            log.debug("查询根级群组列表");
            
            List<MaterialGroupViewEntity> list = materialGroupViewService.getRootGroups();
            return R.ok(list);
            
        } catch (Exception e) {
            log.error("查询根级群组列表失败: error={}", e.getMessage(), e);
            return R.fail("查询根级群组列表失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<MaterialGroupViewEntity>> getByGroupType(String groupType) {
        try {
            log.debug("根据类型查询群组列表: groupType={}", groupType);
            
            List<MaterialGroupViewEntity> list = materialGroupViewService.getByGroupType(groupType);
            return R.ok(list);
            
        } catch (Exception e) {
            log.error("根据类型查询群组列表失败: groupType={}, error={}", groupType, e.getMessage(), e);
            return R.fail("根据类型查询群组列表失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<MaterialGroupViewEntity>> getActiveGroups() {
        try {
            log.debug("查询启用状态的群组列表");
            
            List<MaterialGroupViewEntity> list = materialGroupViewService.getActiveGroups();
            return R.ok(list);
            
        } catch (Exception e) {
            log.error("查询启用状态的群组列表失败: error={}", e.getMessage(), e);
            return R.fail("查询启用状态的群组列表失败: " + e.getMessage());
        }
    }
}